package com.zx.baofu.alcohol.wx;

import com.alibaba.fastjson.JSONObject;
import com.zx.baofu.alcohol.model.Result;
import com.zx.baofu.alcohol.util.HttpUtil;
import com.zx.baofu.alcohol.util.MyStringUtil;
import com.zx.baofu.alcohol.util.RedisUtil;
import com.zx.baofu.alcohol.util.SHA1;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@Log4j2
@RestController
@RequestMapping(value = "/wx", method = RequestMethod.GET)
public class WeiXinController {
//    private static final String APP_ID = "wxf1ad2e5ebcee7007";
//    private static final String APP_SECRET = "715fff28712ffbf4e3f3abf8ec47a99e";
    private static final String APP_ID = "wxc873bd34f787b846";
    private static final String APP_SECRET = "0769f2c3df72e763183be1b30128dcc4";
    private static final String NONCESTR = "baOfUjiUyE";

    @Autowired
    private RedisUtil redisUtil;

    /**
     *
     * @param code
     * @return {"openid":" OPENID"," nickname":NICKNAME,"sex":"1","province":"PROVINCE""city":"CITY","country":"COUNTRY","headimgurl":"http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46","privilege":["PRIVILEGE1""PRIVILEGE2"],"unionid":"o6_bmasdasdsad6_2sgVt7hMZOPfL"}
     */
    @RequestMapping(value = "/userInfo")
    public Result userInfoByCode(String code){
        JSONObject accessJson = accessTokenByCode(code);
        //log.info("accessJson" + JSONObject.toJSONString(accessJson));
        if (accessJson.containsKey("errcode")){
            return new Result().fail("获取accessToken失败，请重试");
        }
        String accessToken = accessJson.getString("access_token");
        String openId = accessJson.getString("openid");
        JSONObject userJson = userByAccessToken(accessToken, openId);
        //log.info("userJson" + JSONObject.toJSONString(userJson));
        if (userJson.containsKey("errcode")){
            return new Result().fail("获取用户信息失败，请重试");
        }
        return new Result().success("获取信息成功", userJson);
    }

    /**
     * 通过code换取accessToken
     * @param code
     * @return
     */
    private static JSONObject accessTokenByCode(String code){
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token";
        String param = "appid="+ APP_ID +"&secret="+ APP_SECRET +"&code="+ code +"&grant_type=authorization_code";
        String responseStr = HttpUtil.sendGet(url, param);
        JSONObject response = JSONObject.parseObject(responseStr);
        return response;
    }

    /**
     * 拉取用户信息
     * @param accessToken
     * @param openId
     * @return
     */
    private static JSONObject userByAccessToken(String accessToken, String openId){
        String url = "https://api.weixin.qq.com/sns/userinfo";
        String param = "access_token="+ accessToken +"&openid="+ openId +"&lang=zh_CN";
        String responseStr = HttpUtil.sendGet(url, param);
        JSONObject response = JSONObject.parseObject(responseStr);
        return response;
    }

    /**
     * 获取公众平台的API调用所需的access_token(普通的Accesstoken)
     * @return
     */
    private static JSONObject commonAccessToken(){
        String url = "https://api.weixin.qq.com/cgi-bin/token";
        String param = "grant_type=client_credential&appid="+ APP_ID +"&secret="+ APP_SECRET;
        String responseStr = HttpUtil.sendGet(url, param);
        JSONObject response = JSONObject.parseObject(responseStr);
        //response.getIntValue("errcode"); == 0 表示请求成功
        return response;
    }

    private static JSONObject getJsapiTicket(String  accessToken){
        String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
        String param = "access_token="+ accessToken +"&type=jsapi";
        String responseStr = HttpUtil.sendGet(url, param);
        JSONObject response = JSONObject.parseObject(responseStr);
        return response;
    }

    /**
     *
     * @param url 当前网页的URL，不包含#及其后面部分
     * @return {"code":200,"data":{"signature":"026801b19c3e5ee376e85f32cc4e13d5906606a9","nonceStr":"baOfUjiUyE","timestamp":"1575856633"},"msg":"查询完成"}
     */
    @RequestMapping(value = "/getSignature")
    public Result getSignature(String url){
        String ticket = "";
        ticket = redisUtil.get("wxJspApiTicket");
        if (MyStringUtil.isNullorEmpty(ticket)){
            //获取jspapi ticket
            JSONObject accessTokenJson = commonAccessToken();
            if (accessTokenJson.getIntValue("errcode") != 0){
                return new Result().fail("获取accessToken失败:" + accessTokenJson.getIntValue("errcode") + "原因:" + accessTokenJson.getIntValue("errmsg"));
            }
            String accessToken = accessTokenJson.getString("access_token");
//            log.info("getSignature -- accessToken : " + accessToken);
            JSONObject ticketJson = getJsapiTicket(accessToken);
            if (ticketJson.getIntValue("errcode") != 0){
                return new Result().fail("获取ticket失败:" + ticketJson.getIntValue("errcode") + "原因:" + ticketJson.getIntValue("errmsg"));
            }
            ticket = ticketJson.getString("ticket");

            int expiresIn =  ticketJson.getInteger("expires_in");
            //ticket加入缓存
            redisUtil.set("wxJspApiTicket", ticket, (expiresIn - 200));
        }
        String timestamp = String.valueOf((int)(System.currentTimeMillis() / 1000));

        //加密生成signature
        String signature = getSHA1(NONCESTR, ticket, timestamp, url);
        JSONObject res = new JSONObject();
        res.put("timestamp", timestamp);
        res.put("signature", signature);
        res.put("nonceStr", NONCESTR);
        return new Result().success("查询完成", res);
    }

    private String getSHA1(String noncestr, String ticket, String timestamp, String url){
        String string1 = "jsapi_ticket="+ ticket +"&noncestr="+ noncestr +"&timestamp="+ timestamp +"&url=" + url;
        //log.info("getSHA1 -- string1 : " + string1);
        String signature = SHA1.encode(string1);
        return signature;
    }
}
